// 生成令牌（token）和取消函数（cancel）
import { CancelExecutor, Canceler, CancelTokenSource } from '../types'
import Cancel from './Cancel'

interface ResolvePromise {
  // (reason?: Cancel): void
  (value: Cancel | PromiseLike<Cancel>): void // (豆包）必须包含 value 参数，非可选
}

export default class CancelToken {
  promise: Promise<Cancel>
  reason?: Cancel

  constructor(executor: CancelExecutor) { // executor是创建令牌时传入的回调
    let resolvePromise: ResolvePromise

    this.promise = new Promise<Cancel>(resolve => {
      resolvePromise = resolve  // 用来记录 “是否被取消”
    })

    executor(message => { // 调用executor，传入取消回调  即 设置按钮功能((取消原因) => { 
      if (this.reason) { // 如果已经取消过，直接返回（避免重复取消）
        return
      }
      this.reason = new Cancel(message) // 创建Cancel实例，保存取消原因
      resolvePromise(this.reason) // 解析Promise，通知外界请求已取消
    })
  }

  throwIfRequested(): void { // 检查是否已取消）
    if (this.reason) {   // 如果reason存在，说明请求已被取消
      throw this.reason// 抛出Cancel错误，终止请求处理
    }
  }

  // 静态工厂方法：生成配对的 cancel 函数和 token
  static source(): CancelTokenSource {
    let cancel!: Canceler // 声明cancel变量（类型为Canceler，即函数）
    const token = new CancelToken(c => { // 创建CancelToken实例
      cancel = c  // 将executor的参数c赋值给cancel（c就是取消回调）
    })
    return {  // 返回包含cancel函数和token的对象
      cancel,
      token
    }
  }
}

